<template>
  <div class="button-function">
    <je-panel>
      <template #tbar>
        <div class="top">
          <je-button type="text" @click="showModal({ type: 'AddButton' })">
            <i class="fal fa-plus-circle"></i> 添加
          </je-button>
          <je-button type="text" @click="handleUpdate">
            <i class="fal fa-save"></i> 保存
          </je-button>
          <je-button type="text" @click="handleDelete">
            <i class="fal fa-times"></i> 删除
          </je-button>
          <div class="searchWrap">
            <je-input-search
              v-model:value.trim="searchValue"
              class="search"
              placeholder="搜索"
              allow-clear
              enter-button="搜索"
              style="width: 280px"
              @search="getData"
            >
              <template #prefix> <i class="fal fa-search" /> </template>
            </je-input-search>
          </div>
        </div>
      </template>
      <template #default>
        <div class="table">
          <je-table
            ref="xTable"
            border
            stripe
            auto-resize
            sync-resize
            show-overflow="ellipsis"
            keep-source
            show-header-overflow
            resizable
            draggable
            header-align="center"
            height="100%"
            :scroll-y="{ mode: 'wheel' }"
            :edit-config="{
              trigger: 'click',
              mode: 'cell',
              showUpdateStatus: true,
            }"
            :edit-rules="validRules"
            :row-config="{ isCurrent: true, isHover: true }"
            :loading="loading"
            :store="gridStore"
            size="mini"
            id-property="JE_CORE_RESOURCEBUTTON_ID"
            @checkbox-change="selectionChange"
            @checkbox-all="selectionChange"
            @drop="buttonItemDrop"
          >
            <je-table-column
              type="checkbox"
              width="40"
              align="center"
              fixed="left"
            ></je-table-column>
            <je-table-column
              field="SY_ORDERINDEX"
              title="序号"
              width="60"
              align="center"
              :edit-render="{}"
              fixed="left"
            >
              <template #edit="{ row }">
                {{ row.SY_ORDERINDEX }}
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_CODE"
              title="编码"
              min-width="220"
              :edit-render="{ autofocus: '.ant-input' }"
              fixed="left"
            >
              <template #default="{ row }">
                <span v-html="formatHightText(searchValue, row.RESOURCEBUTTON_CODE)"></span>
              </template>
              <template #edit="{ row }">
                <je-input v-model:value="row.RESOURCEBUTTON_CODE" />
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_NAME"
              title="名称"
              min-width="140"
              fixed="left"
              :edit-render="{ autofocus: '.ant-input' }"
            >
              <template #default="{ row }">
                <span v-html="formatHightText(searchValue, row.RESOURCEBUTTON_NAME)"></span>
              </template>
              <template #edit="{ row }">
                <je-input v-model:value="row.RESOURCEBUTTON_NAME" />
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_TYPE"
              title="类型"
              align="center"
              min-width="180"
              :edit-render="{}"
              fixed="left"
            >
              <template #edit="{ row }">
                <je-select
                  v-model:value="row.RESOURCEBUTTON_TYPE"
                  allow-clear
                  config-info="JE_FUNC_BUTTON_TYPE,row.RESOURCEBUTTON_TYPE,code,S"
                />
              </template>
              <template #default="{ row }">{{
                getSelectCodeToLabel('JE_FUNC_BUTTON_TYPE', row.RESOURCEBUTTON_TYPE)
              }}</template>
            </je-table-column>
            <!-- <je-table-column
              field="RESOURCEBUTTON_USE_SCOPE"
              title="适用范围"
              align="center"
              min-width="120"
              :edit-render="{}"
            >
              <template #edit="{ row }">
                <je-select
                  v-model:value="row.RESOURCEBUTTON_USE_SCOPE"
                  config-info="JE_META_USE_SCOPE,RESOURCEBUTTON_USE_SCOPE,code,S"
                ></je-select>
              </template>
              <template #default="{ row }">{{
                getSelectCodeToLabel('JE_META_USE_SCOPE', row.RESOURCEBUTTON_USE_SCOPE)
              }}</template>
            </je-table-column> -->
            <je-table-column
              title="事件"
              width="80"
              align="center"
              field="RESOURCEBUTTON_JSLISTENER"
            >
              <template #default="{ row }">
                <je-tooltip placement="top" title="编辑">
                  <div class="iconWrap" @click="handleJs(row)"
                    ><i
                      class="fas fa-bolt"
                      :style="`color:${
                        changeJsListener(row.RESOURCEBUTTON_JSLISTENER) ? '#F4CE4A' : '#8d98ab'
                      }`"
                    ></i
                  ></div>
                </je-tooltip>
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_HIDDEN"
              title="隐藏"
              align="center"
              width="80"
              type="switch"
            />
            <je-table-column
              field="RESOURCEBUTTON_DISABLED"
              title="禁用"
              align="center"
              width="80"
              type="switch"
            />
            <je-table-column title="授权" width="50" align="center">
              <template #default="{ row }">
                <je-tooltip placement="top" title="授权给开发人员">
                  <div class="iconWrap" @click="handleButtonPerm(row)">
                    <i class="jeicon jeicon-seal"></i>
                  </div>
                </je-tooltip>
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_ICON"
              title="字体图标"
              min-width="180"
              :edit-render="{}"
            >
              <template #edit="{ row }">
                <je-icon v-model:value="row.RESOURCEBUTTON_ICON" />
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_ICONCOLOR"
              title="图标颜色"
              min-width="140"
              align="center"
              :edit-render="{}"
            >
              <template #default="{ row }">
                <div class="icon-color-location">
                  <div
                    class="icon-color-bg"
                    :style="`background:${row.RESOURCEBUTTON_ICONCOLOR}; `"
                  ></div
                  >{{ row.RESOURCEBUTTON_ICONCOLOR }}
                </div>
              </template>
              <template #edit="{ row }">
                <je-color v-model:value="row.RESOURCEBUTTON_ICONCOLOR" />
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_BGCOLOR"
              title="样式"
              min-width="180"
              :edit-render="{}"
              style="text-align: center"
            >
              <template #edit="{ row }">
                <div style="padding: 0 10px">
                  <je-button
                    v-if="row.RESOURCEBUTTON_TYPE != 'ACTION'"
                    :style="`font-size: 13px;width: 100%;background:${row.RESOURCEBUTTON_BGCOLOR};color: ${row.RESOURCEBUTTON_FONTCOLOR};border: 1px solid ${RESOURCEBUTTON_BORDERCOLOR};height: 24px; line-height: 100%;`"
                    class="btn-common-overflow"
                    >{{ row.RESOURCEBUTTON_NAME }}</je-button
                  >
                  <je-button
                    v-else
                    class="btn-class btn-common-overflow"
                    @click="showModal({ type: 'Cls', row })"
                    >{{ row.RESOURCEBUTTON_NAME }}</je-button
                  >
                </div>
              </template>
              <template #default="{ row }">
                <je-button
                  v-if="row.RESOURCEBUTTON_BGCOLOR"
                  class="btn-common-overflow"
                  :style="`font-size: 13px;width: 100%;background:${row.RESOURCEBUTTON_BGCOLOR};color: ${row.RESOURCEBUTTON_FONTCOLOR};border: 1px solid ${RESOURCEBUTTON_BORDERCOLOR};height: 24px; line-height: 100%;`"
                  @click="showModal({ type: 'Cls', row })"
                  >{{ row.RESOURCEBUTTON_NAME }}</je-button
                >
                <je-button
                  v-else
                  class="btn-class btn-common-overflow"
                  @click="showModal({ type: 'Cls', row })"
                  >{{ row.RESOURCEBUTTON_NAME }}</je-button
                >
              </template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_POSITION"
              title="按钮条位置"
              width="220"
              align="center"
              :edit-render="{}"
            >
              <template #edit="{ row }">
                <je-select
                  v-model:value="row.RESOURCEBUTTON_POSITION"
                  mode="multiple"
                  :max-tag-count="1"
                  :show-search="false"
                  allow-clear
                  show-arrow
                >
                  <je-select-option
                    v-for="(item, index) in [
                      { value: 'BAR', label: '按钮条' },
                      { value: 'MORE', label: '更多按钮' },
                      { value: 'MULTI', label: '多选按钮条' },
                    ]"
                    :key="index"
                    :value="item.value"
                  >
                    {{ item.label }}
                  </je-select-option>
                </je-select>
              </template>
              <template #default="{ row }">{{
                getSelectMultipleLabel(row.RESOURCEBUTTON_POSITION, [
                  { value: 'BAR', label: '按钮条' },
                  { value: 'MORE', label: '更多按钮' },
                  { value: 'MULTI', label: '多选按钮条' },
                ])
              }}</template>
            </je-table-column>
            <je-table-column
              field="RESOURCEBUTTON_INTERPRETER"
              title="显隐表达式"
              min-width="250"
              :edit-render="{ autofocus: '.ant-input' }"
            >
              <template #edit="{ row }">
                <je-input v-model:value="row.RESOURCEBUTTON_INTERPRETER">
                  <template #suffix>
                    <i
                      class="setIcon fal fa-cog"
                      @click="
                        showExpress(
                          {
                            key: 'RESOURCEBUTTON_INTERPRETER',
                            value: row.RESOURCEBUTTON_INTERPRETER,
                          },
                          row,
                        )
                      "
                    ></i>
                  </template>
                </je-input>
              </template>
            </je-table-column>
            <!-- <je-table-column
              field="RESOURCEBUTTON_FORMBIND"
              title="绑定表单"
              align="center"
              width="100"
              type="switch"
            /> -->
            <je-table-column
              field="RESOURCEBUTTON_NOREADONLY"
              title="不受控"
              align="center"
              width="100"
              type="switch"
            />
            <!-- <je-table-column
              field="RESOURCEBUTTON_MSG"
              title="提示信息"
              min-width="220"
              :edit-render="{ autofocus: '.ant-input' }"
            >
              <template #edit="{ row }">
                <je-input v-model:value="row.RESOURCEBUTTON_MSG" />
              </template>
            </je-table-column> -->
            <!-- <je-table-column
              field="RESOURCEBUTTON_YFAN"
              title="依附按钮"
              min-width="140"
              align="center"
              :edit-render="{}"
            >
              <template #default="{ row }">{{
                getSelectLabel(row.RESOURCEBUTTON_YFAN, pressButton)
              }}</template>
              <template #edit="{ row }">
                <je-select
                  v-model:value="row.RESOURCEBUTTON_YFAN"
                  :options="getOptions(row, pressButton)"
                  allow-clear
                  show-arrow
                />
              </template>
            </je-table-column> -->
          </je-table>
        </div>
      </template>
    </je-panel>

    <div v-if="modalOption.modalFlag">
      <component
        :is="modalOption.activeModal"
        :visble="modalOption.modalFlag"
        :record-data="recordData"
        :select-data="selectData"
        @changeModal="changeModal"
      ></component>
    </div>
  </div>
</template>

<script>
  import { ref, toRefs, reactive, defineComponent, onMounted, onBeforeMount, nextTick } from 'vue';
  import { Tooltip } from 'ant-design-vue';
  import {
    Grid,
    Modal,
    Icon,
    Color,
    Panel,
    InputSelect,
    Button,
    Input,
    Checkbox,
    Select,
    Data,
  } from '@jecloud/ui';

  import { getDDItemInfo, isNotEmpty, loadDDItemByCodes } from '@jecloud/utils';

  import { BUTTON_COMPONENTS } from '@/helper/button-components';

  import { formatHightText } from '@/helper/common.js';

  import { ButtonGet, ButtonUpdate, ButtonRemove, ButtonPerm } from '@/api/index';

  import { listenerEditorModal, ListenerExpressModal } from '@/helper/index.js';

  import { ClsModal } from './components/cls.jsx';

  import { useFuncStore } from '@/store/func-store';

  export default defineComponent({
    name: 'Button',
    components: {
      JeTable: Grid,
      JeTableColumn: Grid.Column,
      JeInput: Input,
      JeInputSearch: Input.Search,
      JeCheckbox: Checkbox,
      JeSelect: Select,
      JeSelectOption: Select.Option,
      JeButton: Button,
      JeTooltip: Tooltip,
      JeIcon: Icon,
      JeColor: Color,
      JePanel: Panel,
      JeGridSelect: InputSelect.Grid,
      ...BUTTON_COMPONENTS,
    },
    props: {
      recordData: {
        type: Object,
        default: () => {},
      },
    },
    setup(props) {
      const state = reactive({
        pressButton: [],
        selectData: {},
        xTable: ref(),
        funcId: props.recordData.JE_CORE_FUNCINFO_ID,
        gridStore: Data.Store.useGridStore({
          data: [],
        }),
        selectTableData: [],
        loading: true,
        validRules: ref({
          RESOURCEBUTTON_CODE: [
            {
              required: true,
              message: '该输入项为必填项',
            },
            { max: 40, message: '不能大于40个字符' },
          ],
          RESOURCEBUTTON_NAME: [
            {
              required: true,
              message: '该输入项为必填项',
            },
            { max: 40, message: '不能大于40个字符' },
          ],
        }),
        searchValue: '',
        formatHightText,
        querysArr: [
          {
            code: 'RESOURCEBUTTON_FUNCINFO_ID',
            value: props.recordData.id,
            type: '=',
            cn: 'and',
          },
        ],
      });

      const modalOption = reactive({
        modalFlag: false, // 默认modal都是隐藏的false
        activeModal: '', // 默认没有激活的弹窗类型
      });

      const menuActive = reactive({ show: '', recordData: props.recordData });

      //弹出关闭回调
      const btnClick = (obj) => {
        if (obj.type == 'close') {
          menuActive.show = '';
        }
      };

      //弹出代码编辑器
      const handleJs = (row) => {
        listenerEditorModal({
          funcId: props.recordData.id,
          funcCode: props.recordData.code,
          funcName: props.recordData.text,
          onId: row.JE_CORE_RESOURCEBUTTON_ID,
          eventType: row.RESOURCEBUTTON_TYPE == 'ACTION' ? 'actioncolumn' : 'button',
          title: row.RESOURCEBUTTON_TYPE == 'ACTION' ? 'Action按钮事件' : '按钮事件',
          callback: (obj) => {
            row.RESOURCEBUTTON_JSLISTENER = obj.data;
          },
        });
      };

      const methods = {
        getOptions(row, data) {
          data.forEach((item) => {
            item.disabled = false;
            if (item.value == row.RESOURCEBUTTON_CODE) {
              item.disabled = true;
            }
          });
          return data;
        },
        // 是否将事件的图标点亮
        changeJsListener(data) {
          if (!data || !data.trim()) return false;
          const parseData = data ? JSON.parse(data) : [];
          let eventType = false;
          if (Array.isArray(parseData)) {
            parseData.forEach((item) => {
              if (item.fire == '1') {
                eventType = true;
              }
            });
          } else {
            eventType = parseData.fire == '1';
          }

          return eventType;
        },
        // 显隐藏表达式
        showExpress(obj, row) {
          obj.funcId = props.recordData.id;
          ListenerExpressModal({
            ...obj,
            callback: (res) => {
              row[obj.key] = res.value;
            },
          });
        },
        // 按钮排序
        buttonItemDrop() {
          state.gridStore.data.forEach((item, index) => {
            item.SY_ORDERINDEX = index + 1;
          });
        },
        showModal(obj) {
          // if (obj.row && obj.row.RESOURCEBUTTON_TYPE == 'ACTION') {
          //   Modal.alert('action列不支持按钮样式配置!', 'info');
          //   return false;
          // }
          if (obj.type === 'Cls') {
            state.selectTableData = [obj.row];
            state.selectData = { ...obj.row };
            ClsModal({
              title: '按钮样式',
              selectData: state.selectData,
              callback: (res) => {
                let findIndex = '';
                findIndex = state.gridStore.data.findIndex(
                  (item) =>
                    item.JE_CORE_RESOURCEBUTTON_ID ===
                    state.selectTableData[0].JE_CORE_RESOURCEBUTTON_ID,
                );
                const {
                  RESOURCEBUTTON_BGCOLOR,
                  RESOURCEBUTTON_FONTCOLOR,
                  RESOURCEBUTTON_BORDERCOLOR,
                } = res;
                state.gridStore.data[findIndex].RESOURCEBUTTON_BGCOLOR = RESOURCEBUTTON_BGCOLOR;
                state.gridStore.data[findIndex].RESOURCEBUTTON_FONTCOLOR = RESOURCEBUTTON_FONTCOLOR;
                state.gridStore.data[findIndex].RESOURCEBUTTON_BORDERCOLOR =
                  RESOURCEBUTTON_BORDERCOLOR;
              },
            });
          } else {
            modalOption.modalFlag = true;
            modalOption.activeModal = obj.type;
          }
        },

        changeModal(obj) {
          modalOption.modalFlag = obj.visble;

          if (obj.type === 'refreshData') {
            // methods.getData();
            state.gridStore.insert(obj.data);
          }
        },

        selectionChange(obj) {
          state.selectTableData = obj.records;
        },

        getSelectLabel(value, list, valueProp = 'value', labelField = 'label') {
          const item = list.find((item) => item[valueProp] === value);
          return item ? item[labelField] : null;
        },
        getSelectCodeToLabel(dictionary, code) {
          const item = getDDItemInfo(dictionary, code);

          if (isNotEmpty(item)) {
            return item.text;
          }
          return '';
        },
        getSelectMultipleLabel(value, list, valueProp = 'value', labelField = 'label') {
          return value
            .map((val) => {
              const item = list.find((item) => item[valueProp] === val);
              return item ? item[labelField] : null;
            })
            .join(',');
        },

        handleButtonPerm(row) {
          const funcStore = useFuncStore();
          const params = {
            // pkValue: row.JE_CORE_RESOURCEBUTTON_ID,
            // funcId: state.funcId,
            funcCode: props.recordData.code,
            buttonCode: row.RESOURCEBUTTON_CODE,
            productId: funcStore.product.id,
          };

          ButtonPerm(params)
            .then((res) => {
              Modal.message(res.message, 'success');
            })
            .catch((error) => {
              Modal.alert(error.message, 'error');
            });
        },

        // 获取 table 数据
        getData() {
          state.loading = true;
          const params = {
            tableCode: 'JE_CORE_RESOURCEBUTTON',
            baseSql: ` and RESOURCEBUTTON_FUNCINFO_ID = '${state.funcId}'`,
            funcId: state.funcId,
            j_query: JSON.stringify({
              custom: [
                {
                  code: 'RESOURCEBUTTON_FUNCINFO_ID',
                  value: state.funcId,
                  type: '=',
                  cn: 'and',
                },
                {
                  type: 'and',
                  value: [
                    {
                      type: 'like',
                      code: 'RESOURCEBUTTON_CODE',
                      value: state.searchValue,
                      cn: 'or',
                    },
                    {
                      type: 'like',
                      code: 'RESOURCEBUTTON_NAME',
                      value: state.searchValue,
                      cn: 'or',
                    },
                  ],
                },
              ],
              order: [{ code: 'SY_ORDERINDEX', type: 'ASC' }],
            }),
            // page: 1,
            // start: 0,
            // limit: -1,
          };

          ButtonGet(params)
            .then((res) => {
              const data = res.rows || [];
              const pressButtons = [];
              data.forEach((item) => {
                Object.keys(item).forEach((key) => {
                  if (key == 'RESOURCEBUTTON_POSITION') {
                    item[key] = item[key] ? item[key].split(',') : [];
                  } else if (key != 'SY_ORDERINDEX') {
                    item[key] = item[key] || '';
                  }
                });
                item.RESOURCEBUTTON_ICONCOLOR = item.RESOURCEBUTTON_ICONCOLOR || '';
                item.RESOURCEBUTTON_BGCOLOR = item.RESOURCEBUTTON_BGCOLOR || '';
                item.RESOURCEBUTTON_FONTCOLOR = item.RESOURCEBUTTON_FONTCOLOR || '';
                item.RESOURCEBUTTON_BORDERCOLOR = item.RESOURCEBUTTON_BORDERCOLOR || '';
                const pressButtonItem = {
                  value: item.RESOURCEBUTTON_CODE,
                  label: item.RESOURCEBUTTON_NAME,
                };
                pressButtons.push(pressButtonItem);
                state.pressButton = pressButtons;
              });

              state.gridStore.loadData(data);

              state.loading = false;
            })
            .catch((error) => {
              Modal.alert(error.message, 'error');
            });
        },

        // 保存
        handleUpdate() {
          const updateRecords = state.gridStore.getChanges();
          if (updateRecords.length === 0) {
            Modal.message('无数据操作!', 'info');
            return false;
          }
          // 校验必填项

          const data = [];
          const changeData = [];
          updateRecords.forEach((item) => {
            data.push(item._record);
            const changeItem = {
              JE_CORE_RESOURCEBUTTON_ID: item._record.JE_CORE_RESOURCEBUTTON_ID,
            };
            Object.keys(item).forEach((key) => {
              if (key != '_record') {
                changeItem[key] = item[key].newValue || '';
              }
              if (key == 'RESOURCEBUTTON_POSITION') {
                changeItem[key] = item[key].newValue.join(',');
              }
            });
            changeData.push(changeItem);
          });

          state.xTable.$plugin.validate(data, (errMap) => {
            if (errMap) {
              return false;
            } else {
              const params = {
                tableCode: 'JE_CORE_RESOURCEBUTTON',
                funcId: state.funcId,
                strData: JSON.stringify(changeData),
              };

              ButtonUpdate(params)
                .then((res) => {
                  data.forEach((item) => {
                    state.gridStore.commitRecord(item);
                  });
                  Modal.message(res.message, 'success');
                })
                .catch((error) => {
                  Modal.alert(error.message, 'error');
                });
            }
          });
        },
        handleDelete() {
          const len = state.selectTableData.length;

          if (len === 0) {
            Modal.alert('请选择要删除的数据！', 'warning');
            return false;
          }

          Modal.confirm('确定删除选中的数据吗？', () => {
            methods.doDelete();
          });
        },

        doDelete() {
          const ids = state.selectTableData.map((item) => item.JE_CORE_RESOURCEBUTTON_ID).join(',');

          const params = {
            tableCode: 'JE_CORE_RESOURCEBUTTON',
            ids,
          };

          ButtonRemove(params)
            .then((res) => {
              state.selectTableData.forEach((item) => {
                state.gridStore.remove(item);
              });
              Modal.message(res.message, 'success');
              state.selectTableData = [];
            })
            .catch((error) => {
              Modal.alert(error.message, 'error');
            });
        },
      };
      onBeforeMount(() => {
        // 获取字典数据
        loadDDItemByCodes(['JE_FUNC_BUTTON_TYPE', 'JE_META_USE_SCOPE']);
      });
      onMounted(() => {
        nextTick(() => {
          methods.getData();
        });
      });

      return {
        ...toRefs(state),
        ...methods,
        modalOption,
        handleJs,
        menuActive,
        btnClick,
      };
    },
  });
</script>
<style lang="less" scoped>
  .button-function {
    // position: relative;
    width: 100%;
    height: 100%;
    .btn-class {
      background: @primary-color;
      width: 100%;
      color: #fff;
      height: 24px;
      line-height: 100%;
      font-size: 13px;
    }
    .icon-color-location {
      display: flex;
      align-items: center;
      justify-content: center;
      .icon-color-bg {
        width: 14px;
        height: 14px;
        border: 1px solid transparent;
        margin-right: 3px;
      }
    }

    .searchWrap {
      margin: 0 0 0 auto;
      .ant-input-search {
        border-bottom-right-radius: 0;
        border-top-right-radius: 0;
      }
      .ant-input-affix-wrapper-focused {
        box-shadow: none !important;
      }
      .ant-btn {
        width: 60px;
        background: #3265f5;
      }
    }
    .top {
      display: flex;
      align-items: center;
      height: 40px;
      padding: 0 20px 0 4px;
      background: #f7f9fc;
      > .ant-btn {
        padding: 4px 12px !important;
        &:hover {
          color: #3f3f3f !important;
          background: #d9d9d9 !important;
        }
      }
    }
    .table {
      .iconWrap {
        cursor: pointer;
      }
    }
  }
</style>
<style>
  .btn-common-overflow span {
    width: 100%;
    -webkit-line-clamp: 1;
    /* 设置或检索伸缩盒对象的子元素的排列方式 */
    -webkit-box-orient: vertical;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
</style>
